Codepipelineのデプロイが完了したらどのバージョンをデプロイしたのかをCFn一撃通知してみる
梶原大使at福岡です。
Codepipelineのデプロイが完了したらCodepipelineがどのバージョンをデプロイしたのかSNS通知(メール)してみます。
さっそくですが、 つ CloudFormationテンプレート
ってことで、CFn一撃化して必要なのはメアドだけにしておきました。 テンプレートも載せていますのでカスタマイズはご自由に。
構成図はこんな感じです。
いるもの
AWSアカウント(各種権限)
各種設定
CloudWatch Events Rule
- ソース: CodePipeline
- イベントタイプ:CodePipelineの状態変更
- 状態: 成功 or 失敗
CodePipelineCwEventsRule: Type: AWS::Events::Rule Properties: EventPattern: source: - aws.codepipeline detail-type: - CodePipeline Pipeline Execution State Change detail: state: - SUCCEEDED - FAILED State: ENABLED Targets: - Id: "CodePipelineGetExecutionLambda" Arn: !GetAtt CodePipelineGetExecutionFunction.Arn
成功、失敗以外に欲しい状態があれば、stateに追加してください。
Lambdaでやっている事
- イベント通知からパイプライン名、実行IDを取得
- デプロイの詳細情報を取得(getPipelineExecution)
- デプロイの詳細情報をSNS通知
特に迷うところはないかと。
ちょっと注意
コンソールで設定した場合はよしなにやってくれるのですが CloudFormationの場合はEventsからLambdaを呼び出すので Lambda側に許可設定を実施します
LambdaInvokePermission: Type: AWS::Lambda::Permission Properties: FunctionName: !GetAtt CodePipelineGetExecutionFunction.Arn Action: lambda:InvokeFunction Principal: events.amazonaws.com SourceArn: !GetAtt CodePipelineCwEventsRule.Arn
やってみる
CloudFormationの実行
最後のテンプレートをCloudFormationで実行してください。
CodepipeLineの実行
Codepipelineの実行が成功/失敗すると下記のようなメールが通知されます。 まんま、getPipelineExecutionの中身になりますが
見るべきところは
- pipelineName:パイプライン名
- status: デプロイ結果正常終了時は
Succeeded
, 失敗時はFailed
- revisionId: githbuやCodecommitの場合はコミットのハッシュ値
- revisionSummary: githubやCodecommitの場合はコミット時のコメント
- revisionUrl: 何気にコミット時の差異がみれるので便利かも? (前回のデプロイの差異とかではなくあくまでコミット時の差分です)
になります。
件名:CodePipeline Execution Succeeded
{ "pipelineExecution": { "pipelineName": "temp-pipeline-hogehoge", "pipelineVersion": 1, "pipelineExecutionId": "XXXX-YYYY-ZZZ-1111-XXXXX", "status": "Succeeded", "artifactRevisions": [ { "name": "SourceArtifact", "revisionId": "XXXXXXXXXXXXXXXXXXXXXXXXXXXX", "revisionSummary": "update hoge\n", "revisionUrl": "https://ap-northeast-1.console.aws.amazon.com/codecommit/home#/repository/repo/commit/XXXXXXXXXXXXXXXXX" } ] } }
まとめ
Pipeline Execution State Changeの通知だけでも失敗、成功は判別できますが どのリビジョンがデプロイされたか知りたかったので作ってみました。 どなたかの役に立てば幸いです。
テンプレート全体
AWSTemplateFormatVersion: '2010-09-09' Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: "SNS Settings" Parameters: - EMailAddress ParameterLabels: EMailAddress: default: "E-Mail Address" Parameters: EMailAddress: Type: String Default: hogefuga@exsample.com Resources: EMailSNSTopic: Type: AWS::SNS::Topic Properties: Subscription: - Endpoint: !Ref EMailAddress Protocol: email CodePipelineCwEventsRule: Type: AWS::Events::Rule Properties: EventPattern: source: - aws.codepipeline detail-type: - CodePipeline Pipeline Execution State Change detail: state: - SUCCEEDED - FAILED State: ENABLED Targets: - Id: "CodePipelineGetExecutionLambda" Arn: !GetAtt CodePipelineGetExecutionFunction.Arn CodePipelineGetExecutionFunction: Type: AWS::Lambda::Function Properties: Handler: index.handler Role: !GetAtt LambdaExecutionRole.Arn Environment: Variables: SNS_TOPIC_ARN: !Ref EMailSNSTopic Code: ZipFile: !Sub | var AWS = require('aws-sdk'); var SNS_TOPIC_ARN = process.env.SNS_TOPIC_ARN; exports.handler = async(event) => { // console.log(JSON.stringify(event, null, 4)); var codepipeline = new AWS.CodePipeline(); var sns = new AWS.SNS(); var params = { pipelineExecutionId: event.detail['execution-id'], pipelineName: event.detail.pipeline }; var pipelineExecution = await codepipeline.getPipelineExecution(params).promise(); // console.log(JSON.stringify(pipelineExecution, null, 4)); params = { Message: JSON.stringify(pipelineExecution, null, 4), Subject: 'CodePipeline Execution ' + pipelineExecution.pipelineExecution.status, TopicArn: SNS_TOPIC_ARN }; var result = await sns.publish(params).promise(); return result; }; Runtime: nodejs8.10 Timeout: 30 LambdaExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole - arn:aws:iam::aws:policy/AWSCodePipelineReadOnlyAccess Path: "/" Policies: - PolicyName: LambdaExecutionRole-SnsPublishPolicy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - sns:Publish Resource: arn:aws:sns:*:*:* LambdaInvokePermission: Type: AWS::Lambda::Permission Properties: FunctionName: !GetAtt CodePipelineGetExecutionFunction.Arn Action: lambda:InvokeFunction Principal: events.amazonaws.com SourceArn: !GetAtt CodePipelineCwEventsRule.Arn